//寄生组合式继承

/*

子类构造函数复制父类的自身属性和方法，子类原型只接收父类的原型属性和方法
所谓寄生组合继承，即通过借用构造函数来继承属性，通过原型链的混成形式来继承方法。
其背后的基本思路是：不必为了指定子类型的原型而调用超类型的构造函数，我们所需要的无非就是超类型的原型的一个副本而已。本质上，就是使用寄生式继承来继承超类型的原型，然后再将结果指定给予类型的原型。


优点： 
这种方式的高效率体现它只调用了一次Parent构造函数，并且因此避免了再Parent.prototype上面创建不必要的，多余的属性。
普遍认为寄生组合式继承是引用类型最理想的继承方式

*/


function Parent(name){
    this.name = name;
    this.colors = ['red', 'blue', 'green'];
}

Parent.prototype.sayName = function(){
    console.log(this.name,this.colors);
}

function Child(name,age){
    Parent.call(this,name); 
    this.age = age;
}

function CreateObj(o){
    function F(){};
    F.prototype = o;
    return new F();
}

Child.prototype = new Parent(); // 这里换成下面
// function prototype(child,parent){
//     var prototype = CreateObj(parent.prototype);
//     prototype.constructor = child;
//     child.prototype = prototype;
// }
// prototype(Child,Parent);

var child1 = new Child('xiaopao1', 17);
var child2 = new Child('xiaopao2', 18);
console.log(child1);    // Parent { name: 'xiaopao1', colors: [ 'red', 'blue', 'green' ], age: 17 }
console.log(child2);    // Parent { name: 'xiaopao2', colors: [ 'red', 'blue', 'green' ], age: 18 }
child1.sayName();  //xiaopao1 [ 'red', 'blue', 'green' ]
child2.sayName();  //xiaopao2 [ 'red', 'blue', 'green' ]
child1.name='new-xiaopao1';
child1.colors.push('lulu');
child2.age=20;
console.log(child1);    // Parent { name: 'new-xiaopao1', colors: [ 'red', 'blue', 'green', 'lulu' ], age: 17 }
child1.sayName();  // new-xiaopao1 [ 'red', 'blue', 'green', 'lulu' ]
child2.sayName();  // xiaopao2 [ 'red', 'blue', 'green' ]
console.log(child1 instanceof Parent); // true
console.log(child1 instanceof Child); // true